/*!
 * \file jboss_comm.c
 *
 * \brief jboss数据包解析
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 *
 * \version 2.0
 * \author geyh
 * \date 2015/11/05
 *
 */
#include <stdlib.h>
#include <stdio.h>

#include "frcomm.h"
#include "frmem.h"
#include "iconv2utf8.h"
#include "jbossmq_comm.h"

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};

/*!
 * jboss boolean 解析
 *
 * \param *p_st_data        (Frbyte_Packet   数据包内容)
 *
 * \return 1:true\n
 *         0:false
 *
 */
int jboss_boolean_parse(Frbyte_Packet *p_st_data)
{
    int i_ret = FR_SUCC;
    int i_boolean = 0;

    if(p_st_data == NULL)
        return FR_FAIL;

    //取得长度  实际长度加倍
    i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_boolean, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return -1;

    return i_boolean;
}


/*!
 * jboss simple string 获取
 *
 * \param *p_st_data        (Frbyte_Packet   数据包内容)
 * \param **pp_simple_str   (char **   双重指针 外部释放内存    )
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_get_simple_string(Frbyte_Packet *p_st_data, char **pp_simple_str, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_data_len = 0, i_tmp_len = 0;
    char *p_data = NULL, *p_out = NULL;

    if(p_st_data == NULL)
        return FR_FAIL;

    //取得长度  实际长度加倍
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_data_len = i_data_len * 2;

    if(pp_simple_str && *pp_simple_str)
    {
        frfree(*pp_simple_str);
        *pp_simple_str = NULL;
    }

    //获取长度
    if(i_flag_need)
    {
        if(pp_simple_str == NULL)
            return FR_FAIL;

        p_data = (char *)frmalloc(i_data_len);
        if(p_data == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_data, i_data_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }

        //转UTF8
        i_ret = iconv_to_utf8(p_data, i_data_len, "UNICODEBIG", &p_out, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
        {
            frfree(p_data);
            return FR_FAIL;
        }
        //内容出力
        frfree(p_data);
        *pp_simple_str = p_out;
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data, i_data_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;

}

/*!
 * jboss string 获取
 *
 * \param *p_st_data        (Frbyte_Packet   数据包内容)
 * \param **pp_str   (char **   双重指针 外部释放内存    )
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_get_string(Frbyte_Packet *p_st_data, char **pp_str, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_data_len = 0, i_tmp_len = 0;
    char *p_data = NULL, *p_out = NULL;

    if(p_st_data == NULL)
        return FR_FAIL;

    //取得长度
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //获取长度
    if(i_flag_need)
    {
        if(pp_str == NULL)
            return FR_FAIL;

        p_data = (char *)frmalloc(i_data_len);
        if(p_data == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_data, i_data_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }

        //转UTF8
        i_ret = iconv_to_utf8(p_data, i_data_len, "unicode", &p_out, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
        {
            frfree(p_data);
            return FR_FAIL;
        }
        //内容出力
        frfree(p_data);
        if(*pp_str)
            frfree(*pp_str);
        *pp_str = p_out;
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data, i_data_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;

}


/*!
 * jboss message 获取
 *
 * \param *p_st_data        (Frbyte_Packet   数据包内容)
 * \param **pp_str   (char **   双重指针 外部释放内存    )
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_get_message(Frbyte_Packet *p_st_data, char **pp_str, int *p_i_len, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_data_len = 0, i_tmp_len = 0;
    char *p_data = NULL, *p_out = NULL;

    if(p_st_data == NULL)
        return FR_FAIL;

    //取得长度
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_data_len -= 4;

    //获取长度
    if(i_flag_need)
    {
        if(pp_str == NULL || p_i_len == NULL)
            return FR_FAIL;

        p_data = (char *)frmalloc(i_data_len);
        if(p_data == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_data, i_data_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }

        //转UTF8
        i_ret = iconv_to_utf8(p_data, i_data_len, "unicode", &p_out, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
        {
            frfree(p_data);
            return FR_FAIL;
        }
        //内容出力
        frfree(p_data);
        if(pp_str == NULL)
        {
            frfree(p_out);
            return FR_FAIL;
        }
        *pp_str = p_out;
        *p_i_len = i_data_len;
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data, i_data_len);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;

}

/*!
 * jboss connection 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_connection_parse(Frbyte_Packet *p_st_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_all_len = 0, i_data_len = 0;

    if(p_st_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    p_st_private->i_flag_data_type = FRLOGIN_START;
    //8BYTE  01 跳过
    i_ret = bytebuff_skip(p_st_data, 8);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //数据总长度
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_all_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //跳过 client id  取长度
    i_ret = bytebuff_get_int(p_st_data, 2, (uint32_t *)&i_data_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //跳过内容段
    i_ret = bytebuff_skip(p_st_data, i_data_len);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_all_len -= i_data_len;

    i_ret = bytebuff_skip(p_st_data, 12);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //user name
    i_ret = jboss_boolean_parse(p_st_data);
    if(i_ret < 0)
        return FR_FAIL;

    if(i_ret)
    {
        i_ret = jboss_get_simple_string(p_st_data, &p_st_private->p_user_name, i_flag_need);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data,2);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    //pass word
    i_ret = jboss_boolean_parse(p_st_data);
    if(i_ret < 0)
        return FR_FAIL;

    if(i_ret)
    {
        i_ret = jboss_get_simple_string(p_st_data, NULL, FR_NO);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data,2);
        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    //跳过剩余长度
    i_ret = bytebuff_skip(p_st_data, 12);
    return i_ret;

}

/*!
 * jboss connection 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_connection_out_parse(Frbyte_Packet *p_st_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = FR_SUCC;
    unsigned int ui_response_code = 0;

    if(p_st_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //8BYTE  01 跳过
    i_ret = bytebuff_skip(p_st_data, 8);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //数据总长度
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&ui_response_code, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(ui_response_code == 0x7a)
        p_st_private->i_flag_data_type = FRLOGIN_SUCC;
    else
        p_st_private->i_flag_data_type = FRLOGIN_FAIL;

    return FR_SUCC;
}

/*!
 * jboss logout 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
int jboss_logout_parse(Frbyte_Packet *p_st_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = FR_SUCC;
    uint8_t u8_code = 0;

    if(p_st_data == NULL  || p_st_private == NULL)
        return FR_FAIL;

    //8BYTE  01 跳过
    i_ret = bytebuff_skip(p_st_data, 7);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    i_ret = bytebuff_get_char (p_st_data, &u8_code);

    if(u8_code == 0x0a && p_st_private->i_use_request == FR_NO)
        p_st_private->i_flag_data_type = FRLOGOUT_END;

    return FR_SUCC;
}
/*!
 * jboss sub 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return APM_L7_IS_NO:不属于TCP协议\n
 *         APM_L7_IS_YES:属于TCP协议
 *
 */
int jboss_sub_parse(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_tmp_len = 0;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //8BYTE  01 跳过
    i_ret = bytebuff_skip(p_st_data, 8);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //获取订阅通道
    i_ret = jboss_get_string(p_st_data, &p_st_private->p_title, i_flag_need);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //判断topic  sub上报
    if(i_flag_need)
    {
        i_tmp_len = strlen(p_st_private->p_title) - 5;
        if(strcmp(p_st_private->p_title + i_tmp_len, "Topic") == 0)
        {
            p_st_private->is_topic = 1;
            p_st_private->i_flag_report = 1;
            //sub queue
            if(i_flag_need)
            {
                if(frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_SUB_QUEUE, p_st_private->p_title) == FR_FAIL)
                    return FR_FAIL;
            }
        }
        else
        {
            p_st_private->i_flag_report = 0;
        }
    }

    return FR_SUCC;
}

/*!
 * jboss mapmessage 字段名获取
 *
 * \param **pp_data             (char       入力的数据块)
 * \param *p_i_data_len         (int        入力长度)
 * \param **pp_string           (char       出力的字段)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_get_map_key(char **pp_data, int *p_i_data_len, char **pp_string)
{
    char *p_data = NULL, *p_string = NULL, *p_out = NULL;
    int i_data_len = 0, i_str_len = 0, i_tmp = 0;
    int i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || pp_string == NULL)
        return FR_FAIL;

    p_data = *pp_data;
    i_data_len = *p_i_data_len;

    if(i_data_len < 4)
        return FR_FAIL;

    //获取长度
    i_str_len = pntohi(p_data);
    p_data+=4;
    i_data_len -= 4;

    p_string = (char *)frmalloc(i_str_len + 1);
    if(p_string == NULL)
        return FR_FAIL;

    //map被截断的情况
    if(i_data_len < i_str_len)
    {
        memcpy(p_string, p_data, i_data_len);
        p_data += i_data_len;

        //转码
        i_ret = iconv_to_utf8(p_string, i_data_len, "unicode", &p_out, (unsigned int *)&i_tmp);
        frfree(p_string);
        i_data_len = 0;
    }
    else
    {
        memcpy(p_string, p_data, i_str_len);
        p_data += i_str_len;
        i_data_len -= i_str_len;
        //转码
        i_ret = iconv_to_utf8(p_string, i_str_len, "unicode", &p_out, (unsigned int *)&i_tmp);
        frfree(p_string);
    }

    if(i_ret == 2)
        return FR_FAIL;

    *pp_string = p_out;
    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return FR_SUCC;

}

FR_STATIC int __jboss_get_map_null(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, "null");

    return i_ret;
}

FR_STATIC int __jboss_get_map_byte(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_data_len = 0, i_ret= 0;
    unsigned char uc_byte;
    char *p_data = NULL;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 1)
        return FR_SUCC;

    uc_byte = (unsigned char)*p_data;

    p_data++;
    i_data_len--;

    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, (int) uc_byte);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_boolean(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_data_len = 0, i_ret = 0;
    unsigned char uc_boolean;
    char *p_data = NULL;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 1)
        return FR_SUCC;

    uc_boolean = (unsigned char)*p_data;

    p_data++;
    i_data_len--;

    if(uc_boolean == 0xff)
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, "true");
    else
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, "false");

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_char(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    char *p_data = NULL;
    int i_data_len = 0, i_ret = 0, i_tmp_len;
    char arr_string[3], *p_string = NULL;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 2)
        return FR_SUCC;

//    snprintf(arr_string, sizeof(arr_string), "%s", p_data);
    memcpy(arr_string, p_data, 2);
    arr_string[2] = '\0';

    p_data+=2;
    i_data_len-=2;

    //todo
    i_ret = iconv_to_utf8(arr_string, 2, "UNICODEBIG", &p_string, (unsigned int *)&i_tmp_len);
    if(i_ret == 2)
        return FR_FAIL;

    i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, p_string);

    if(p_string)
        frfree (p_string);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_short(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_value = 0, i_ret = 0;
    char *p_data = NULL;
    int i_data_len = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 2)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    i_value = pntohs(p_data);
    p_data += 2;
    i_data_len -=2;

    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, i_value);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_int(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_value = 0, i_ret = 0;
    char *p_data = NULL;
    int i_data_len = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 4)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    i_value = pntohi(p_data);
    p_data += 4;
    i_data_len -=4;

    i_ret = frreport_body_l7_add_int(p_st_body_data, p_key, i_value);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}


FR_STATIC int __jboss_get_map_long(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    long long ll_value = 0;
    char *p_data = NULL;
    int i_data_len = 0, i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 8)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    ll_value = pntohl(p_data);
    p_data += 8;
    i_data_len -=8;

    i_ret = frreport_body_l7_add_long(p_st_body_data, p_key, ll_value);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}



FR_STATIC int __jboss_get_map_float(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    union int32_float_bits u_32bits;
    uint32_t u32_len = 0;
    float fl_value = 0.0;
    char *p_data = NULL;
    int i_data_len = 0, i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 4)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    u32_len = (uint32_t) pntohi(p_data);
    p_data +=4;
    i_data_len -= 4;

    u_32bits.int_bits = u32_len;
    fl_value = u_32bits.float_bits;

    i_ret = frreport_body_l7_add_float(p_st_body_data, p_key, fl_value);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_double(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    union int64_double_bits u_64bits;
    uint64_t u64_len = 0;
    double db_value = 0.0;
    char *p_data = NULL;
    int i_data_len = 0, i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 8)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    u64_len = pntohl(p_data);
    p_data +=8;
    i_data_len -= 8;

    u_64bits.int_bits = u64_len;
    db_value = u_64bits.double_bits;

    i_ret = frreport_body_l7_add_double(p_st_body_data, p_key, db_value);

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}


FR_STATIC int __jboss_get_map_string(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_str_len = 0, i_data_len = 0, i_tmp_len = 0;
    char *p_string = NULL, *p_data = NULL, *p_out = NULL;
    int i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 4)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    i_str_len = pntohi(p_data);
    p_data+=4;
    i_data_len -= 4;

    if(i_str_len < i_data_len)
    {
        p_string = (char *)frmalloc(i_str_len);
        if(p_string == NULL)
            return FR_FAIL;

        memcpy(p_string, p_data, i_str_len);
        p_data += i_str_len;
        i_data_len -= i_str_len;

        i_ret = iconv_to_utf8(p_string, i_str_len, "unicode", &p_out, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
        {
            frfree(p_string);
            return FR_FAIL;
        }
        frfree(p_string);
        i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, p_out);
    }
    else
    {
        p_string = (char *)frmalloc(i_data_len);
        if(p_string == NULL)
            return FR_FAIL;

        memcpy(p_string, p_data, i_data_len);
        p_data += i_data_len;
        i_ret = iconv_to_utf8(p_string, i_data_len, "unicode", &p_out, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
        {
            frfree(p_string);
            return FR_FAIL;
        }
        frfree(p_string);
        i_data_len = 0;

        i_ret = frreport_body_l7_add_str(p_st_body_data, p_key, p_out);
    }

    frfree(p_out);
    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

FR_STATIC int __jboss_get_map_bytes(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    int i_str_len = 0, i_data_len = 0;
    char *p_data = NULL;
    int i_ret = 0;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    i_data_len = *p_i_data_len;
    p_data = *pp_data;

    if(i_data_len < 4)
    {
        p_data += i_data_len;
        *p_i_data_len = 0;
        return FR_SUCC;
    }

    i_str_len = pntohi(p_data);
    p_data+=4;
    i_data_len -= 4;

    if(i_str_len < i_data_len)
    {
        i_ret = frreport_body_l7_add_bin(p_st_body_data, p_key, p_data, i_str_len);
        i_data_len -= i_str_len;
        p_data += i_str_len;
    }
    else
    {
        i_ret = frreport_body_l7_add_bin(p_st_body_data, p_key, p_data, i_data_len);
        p_data += i_data_len;
        i_data_len = 0;
    }

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;
}

/*!
 * jboss mapmessage value 获取 并上报
 *
 * \param **pp_data             (char       入力的数据块)
 * \param *p_i_data_len         (int        入力长度)
 * \param **pp_string           (char       出力的字段)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_get_map_value(char **pp_data, int *p_i_data_len, char *p_key, Frreport_body_data *p_st_body_data)
{
    char *p_data = NULL;
    int i_data_len = 0;
    int i_ret = 0;
    unsigned char uc_type;

    if(pp_data == NULL || p_i_data_len == NULL || p_key == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_data = *pp_data;
    i_data_len = *p_i_data_len;

    if(i_data_len < 1)
        return FR_FAIL;

    uc_type = *p_data;
    p_data++;
    i_data_len--;

    switch(uc_type)
    {
        case 0x00:
            i_ret = __jboss_get_map_null(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x0b:
            i_ret = __jboss_get_map_char(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x02:
            i_ret = __jboss_get_map_boolean(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x03:
            i_ret = __jboss_get_map_byte(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x04:
            i_ret = __jboss_get_map_bytes(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x05:
            i_ret = __jboss_get_map_short(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x06:
            i_ret = __jboss_get_map_int(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x07:
            i_ret = __jboss_get_map_long(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x08:
            i_ret = __jboss_get_map_float(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x09:
            i_ret = __jboss_get_map_double(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        case 0x0a:
            i_ret = __jboss_get_map_string(&p_data, &i_data_len, p_key, p_st_body_data);
            break;

        default:
            return FR_FAIL;

    }

    *pp_data = p_data;
    *p_i_data_len = i_data_len;
    return i_ret;

}

/*!
 * jboss mapmessage key value 解析
 *
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_message        (char    message 内容)
 * \param uc_message_type   (unsigned char    message 类型 03 text   05  map)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_map_message_parse(Frreport_body_data *p_st_body_data, char *p_data, int i_data_len, L7session_jboss_private *p_st_private)
{
    int i_ret = 0, i_map_count = 0;
    char *p_key = NULL;
    char arr_report_name[128], arr_prifix_name[64];

    if(p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_data == NULL || i_data_len == 0)
        return FR_SUCC;

    if(*p_data == '\01')
    {
        p_data++;
        i_data_len--;

        if(i_data_len < 4)
            return FR_FAIL;

        if(p_st_private->i_use_request)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_METHOD, "put");
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            if(p_st_private->is_topic)
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_QUEUE, p_st_private->p_title);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
            }
            else
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TOPIC, p_st_private->p_title);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
            }

            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TYPE, "map");
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            snprintf(arr_prifix_name, sizeof(arr_prifix_name), "%s", APM_REPORT_KEY_REQ_MAP);

        }
        else
        {
            if(p_st_private->is_topic)
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_QUEUE, p_st_private->p_title);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
            }
            else
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TOPIC, p_st_private->p_title);
                if(i_ret == FR_FAIL)
                    return FR_FAIL;
            }

            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TYPE, "map");
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            snprintf(arr_prifix_name, sizeof(arr_prifix_name), "%s", APM_REPORT_KEY_NTF_MAP);
        }

        //key value 对个数
        i_map_count = pntohi(p_data);
        i_data_len -= 4;
        p_data += 4;

        while(i_map_count)
        {
            //KEY
            i_ret = __jboss_get_map_key(&p_data, &i_data_len, &p_key);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            snprintf(arr_report_name, sizeof(arr_report_name), "%s.%s", arr_prifix_name, p_key);
            frfree(p_key);

            //VALUE
            i_ret = __jboss_get_map_value(&p_data, &i_data_len, arr_report_name, p_st_body_data);
            if(i_ret == FR_FAIL)
                return FR_FAIL;

            i_map_count--;

            if(i_data_len == 0)
                break;
        }
    }

    return FR_SUCC;
}

/*!
 * jboss textmessage key value 解析
 *
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_message        (char    message 内容)
 * \param uc_message_type   (unsigned char    message 类型 03 text   05  map)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_text_message_parse(Frreport_body_data *p_st_body_data, char *p_data, int i_data_len, L7session_jboss_private *p_st_private)
{
    int i_ret = 0;
    char *p_message = NULL, *p_message_content = NULL;
    int i_message_len = 0, i_tmp_len = 0;

    if(p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_data == NULL || i_data_len == 0)
        return FR_SUCC;

    if(*p_data == '\01')
    {
        //message 内容 解析
        p_data++;
        i_data_len --;

        if(i_data_len < 4)
            return FR_FAIL;
        i_message_len = pntohi(p_data);
        p_data += 4;
        i_data_len-=4;
        if(i_message_len > i_data_len)
            return FR_FAIL;

        p_message = p_data;
        p_message[i_message_len] = '\0';

        //编码转换
        i_ret = iconv_to_utf8(p_message, i_message_len, "unicode", &p_message_content, (unsigned int *)&i_tmp_len);
        if(i_ret == 2)
            return FR_FAIL;
    }

    //text
    if(p_st_private->i_use_request)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_METHOD, "put");
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TYPE, "text");
        if(i_ret == FR_FAIL)
            goto ERROR;

        if(p_message_content)
            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, APM_REPORT_KEY_REQ_TEXT, p_message_content);
        else
            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, APM_REPORT_KEY_REQ_TEXT, "\0");

    }
    else
    {
        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TYPE, "text");
        if(i_ret == FR_FAIL)
            goto ERROR;

        if(p_message_content)
            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, APM_REPORT_KEY_NTF_TEXT, p_message_content);
        else
            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, APM_REPORT_KEY_NTF_TEXT, "\0");
    }

    if(p_message_content)
        frfree(p_message_content);
    return i_ret;

ERROR:
    return FR_FAIL;
}


/*!
 * jboss message bin解析
 *
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_message        (char    message 内容)
 * \param uc_message_type   (unsigned char    message 类型 03 text   05  map)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_bin_message_parse(Frreport_body_data *p_st_body_data, char *p_data, int i_data_len, L7session_jboss_private *p_st_private)
{
    int i_ret = 0;
    int i_message_len = 0;

    if(p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_data == NULL || i_data_len == 0)
        return FR_SUCC;

    if(*p_data == '\01')
    {
        //message 内容 解析
        p_data++;
        i_data_len --;

        if(i_data_len < 4)
            return FR_FAIL;
        i_message_len = pntohi(p_data);
        p_data += 4;
        i_data_len-=4;
        if(i_message_len > i_data_len)
            return FR_FAIL;

    }

    //binary
    if(p_st_private->i_use_request)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_METHOD, "put");
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TYPE, "binary");
        if(i_ret == FR_FAIL)
            goto ERROR;

        i_ret = frreport_body_l7_add_bin(p_st_body_data, APM_REPORT_KEY_REQ_BIN, p_data, i_data_len);

    }
    else
    {
        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TYPE, "binary");
        if(i_ret == FR_FAIL)
            goto ERROR;

        i_ret = frreport_body_l7_add_bin(p_st_body_data, APM_REPORT_KEY_NTF_BIN, p_data, i_data_len);
    }

    return i_ret;

ERROR:
    return FR_FAIL;
}

/*!
 * jboss message bin解析
 *
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_message        (char    message 内容)
 * \param uc_message_type   (unsigned char    message 类型 03 text   05  map)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 *
 * \return FR_FAIL:失败\n
 *         FR_SUCC:成功
 *
 */
FR_STATIC int __jboss_stream_message_parse(Frreport_body_data *p_st_body_data, char *p_data, int i_data_len, L7session_jboss_private *p_st_private)
{
    int i_ret = 0;
    int i_message_len = 0;

    if(p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    if(p_data == NULL || i_data_len == 0)
        return FR_SUCC;

    i_message_len = i_data_len - 13;

    if(i_message_len < 0)
        return FR_FAIL;

    //binary
    if(p_st_private->i_use_request)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_METHOD, "put");
        if(i_ret == FR_FAIL)
            return FR_FAIL;

        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_REQ_TYPE, "binary");
        if(i_ret == FR_FAIL)
            goto ERROR;

        i_ret = frreport_body_l7_add_bin(p_st_body_data, APM_REPORT_KEY_REQ_BIN, p_data, i_message_len);

    }
    else
    {
        if(p_st_private->is_topic)
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_QUEUE, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TOPIC, p_st_private->p_title);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_NTF_TYPE, "binary");
        if(i_ret == FR_FAIL)
            goto ERROR;

        i_ret = frreport_body_l7_add_bin(p_st_body_data, APM_REPORT_KEY_NTF_BIN, p_data, i_message_len);
    }

    return i_ret;

    ERROR:
    return FR_FAIL;
}


/*!
 * jboss message 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int jboss_message_parse(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = FR_SUCC;
    int i_tmp_len = 0, i_priority = 0, i_message_len = 0;
    char *p_message = NULL, *p_destination = NULL;
    unsigned char uc_message_type, uc_tmp;

    if(p_st_data == NULL || p_st_body_data == NULL || p_st_private == NULL)
        return FR_FAIL;

    //8BYTE  0b 跳过
    i_ret = bytebuff_skip(p_st_data, 8);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //获取长度
    i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&i_message_len, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //长度包括4位的长度位
    i_message_len -= 4;
    if(i_flag_need)
    {
        p_message = (char *)frmalloc(i_message_len + 1);
        if(p_message == NULL)
            return FR_FAIL;

        //取字符串内容块
        i_ret = bytebuff_get_bytes(p_st_data, p_message, i_message_len);
        if(i_ret == FR_FAIL)
        {
            frfree(p_message);
            return FR_FAIL;
        }
        p_message[i_message_len] = '\0';
    }
    else
    {
        i_ret = bytebuff_skip(p_st_data, i_message_len);
        if(i_ret == FR_FAIL)
            return  FR_FAIL;
    }

    //回滚  取是否有destination
    i_tmp_len = bytebuff_getPosition(p_st_data);
    i_ret = bytebuffer_get_at(p_st_data, i_tmp_len - 1, (uint8_t *)&uc_tmp);
    if(i_ret == FR_FAIL)
        return  FR_FAIL;

    if(uc_tmp == '\x01')
    {
        //p_destination
        if(p_st_private->p_title == NULL && i_flag_need)
        {
            i_ret = jboss_get_string(p_st_data, &p_destination, i_flag_need);
            if(i_ret == FR_FAIL)
            {
                frfree(p_message);
                return FR_FAIL;
            }

            //判断是否为topic
            i_tmp_len = strlen(p_destination) - 5;
            if(strcmp(p_destination + i_tmp_len, "Topic") == 0)
                p_st_private->is_topic = 1;

            p_st_private->p_title = p_destination;
            p_destination = NULL;
        }
        else
        {
            i_ret = jboss_get_string(p_st_data, NULL, FR_NO);
            if(i_ret == FR_FAIL)
            {
                frfree(p_message);
                return FR_FAIL;
            }
        }
    }

    i_ret = bytebuff_skip(p_st_data, 17);
    if(i_ret == FR_FAIL)
    {
        frfree(p_message);
        return FR_FAIL;
    }

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&uc_message_type);
    if(i_ret == FR_FAIL)
    {
        frfree(p_message);
        return FR_FAIL;
    }

    if(i_flag_need)
    {
        if(p_st_private->i_use_request)
        {
            i_ret = frreport_body_l7_add_int(p_st_body_data, "request.mq.message.size", 1);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_int(p_st_body_data, "notify.mq.message.size", 1);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }

        switch (uc_message_type)
        {
            //
            case 0x03:
                //text
                i_ret = __jboss_text_message_parse(p_st_body_data, p_message, i_message_len, p_st_private);
                frfree(p_message);
                break;

            case 0x05:
                // map
                i_ret = __jboss_map_message_parse(p_st_body_data, p_message, i_message_len, p_st_private);
                frfree(p_message);
                break;

            case 0x02:
            case 0x01:
            case 0x04:
                i_ret = __jboss_bin_message_parse(p_st_body_data, p_message, i_message_len, p_st_private);
                frfree(p_message);
                break;

            case 06:
                i_ret = __jboss_stream_message_parse(p_st_body_data, p_message, i_message_len, p_st_private);
                frfree(p_message);
                break;

            default:
                frfree(p_message);
                return FR_FAIL;
        }

        if(i_ret == FR_FAIL)
            return FR_FAIL;
    }

    //跳过17字节
    i_ret = bytebuff_skip(p_st_data, 17);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    //优先级
    i_ret = bytebuff_get_int(p_st_data, 1, (uint32_t *)&i_priority, BYTE_BIG_ENDIAN);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    if(p_st_private->is_topic == 0)
    {
        if(p_st_private->i_use_request)
        {
            i_ret = frreport_body_l7_add_int(p_st_body_data, APM_REPORT_KEY_REQ_PRIORITY, i_priority);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
        else
        {
            i_ret = frreport_body_l7_add_int(p_st_body_data, APM_REPORT_KEY_NTF_PRIORITY, i_priority);
            if(i_ret == FR_FAIL)
                return FR_FAIL;
        }
    }

    return FR_SUCC;
}

/*!
 * jboss message 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return APM_L7_ANALYZE_SUCC:成功\n
 *         APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int jboss_content_parse(Frbyte_Packet *p_st_data, Frreport_body_data *p_st_body_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    unsigned char uc_content_type;

    if(p_st_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_private->i_data_len == 0)
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&p_st_private->i_data_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return APM_L7_ANALYZE_FAIL;
    }

    if((unsigned int)p_st_private->i_data_len > p_st_data->ui_all_len)
        return APM_L7_ANALYZE_TODO;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&uc_content_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(uc_content_type)
    {
        //sub
        case '\x22':
            p_st_private->is_message = 0;
            i_ret = jboss_sub_parse(p_st_data, p_st_body_data, p_st_private, i_flag_need);
            break;

        //message
        case '\x47':
        case '\x4b':
            p_st_private->is_message = 1;
            i_ret = jboss_message_parse(p_st_data, p_st_body_data, p_st_private, i_flag_need);
            break;

        default:
            p_st_private->is_message = 0;
            return APM_L7_ANALYZE_SUCC;
    }

    return i_ret == FR_SUCC ? APM_L7_ANALYZE_SUCC : APM_L7_ANALYZE_FAIL;
}



/*!
 * jboss message 解析
 *
 * \param *p_st_data        (Frbyte_Packet      数据包内容)
 * \param *p_st_body_data   (Frreport_body_data    数据上报链表)
 * \param *p_st_private     (L7session_jboss_private    私有数据)
 * \param i_flag_need       (int    是否获取数据 FR_YES, FR_NO)
 *
 * \return APM_L7_ANALYZE_SUCC:成功\n
 *         APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int jboss_session_parse(Frbyte_Packet *p_st_data, L7session_jboss_private *p_st_private, int i_flag_need)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    unsigned char uc_content_type;

    if(p_st_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_private->i_data_len == 0)
    {
        i_ret = bytebuff_get_int(p_st_data, 4, (uint32_t *)&p_st_private->i_data_len, BYTE_BIG_ENDIAN);
        if(i_ret == FR_FAIL)
            return APM_L7_ANALYZE_FAIL;
    }

    if((unsigned int)p_st_private->i_data_len > p_st_data->ui_all_len)
        return APM_L7_ANALYZE_TODO;

    i_ret = bytebuff_get_char(p_st_data, (uint8_t *)&uc_content_type);
    if(i_ret == FR_FAIL)
        return FR_FAIL;

    switch(uc_content_type)
    {
        //logout
        case '\x15':
            i_ret = jboss_logout_parse(p_st_data, p_st_private, i_flag_need);
            break;

            //connect
        case '\x1e':
            i_ret = jboss_connection_parse(p_st_data, p_st_private, i_flag_need);
            break;

        case '\x1f':
            i_ret = jboss_connection_out_parse(p_st_data, p_st_private, i_flag_need);
            break;

        default:
            return APM_L7_ANALYZE_TODO;
    }

    return i_ret == FR_SUCC ? APM_L7_ANALYZE_SUCC : APM_L7_ANALYZE_FAIL;
}






